import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';
import { BadRequestException } from '@nestjs/common';

/**
 * Scoring模块验证管道
 * 零隐患MFIS规范 - 解决隐患：#11 输入验证，#14 信息泄露
 */
@Injectable()
export class ScoringValidationPipe implements PipeTransform<any> {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }

    // 转换为DTO类实例
    const object = plainToClass(metatype, value);

    // 验证
    const errors = await validate(object, {
      whitelist: true, // 只保留DTO中定义的属性
      forbidNonWhitelisted: true, // 拒绝额外属性
      transform: true, // 自动转换类型
      transformOptions: {
        enableImplicitConversion: true,
      },
    });

    if (errors.length > 0) {
      const validationErrors = this.formatValidationErrors(errors);
      throw new BadRequestException({
        success: false,
        error_code: 'VALIDATION_FAILED',
        message: '输入验证失败',
        details: validationErrors,
        timestamp: new Date().toISOString(),
      });
    }

    return object;
  }

  private toValidate(metatype: any): boolean {
    const types = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }

  private formatValidationErrors(errors: any[]): any {
    return errors.map(error => ({
      field: error.property,
      constraints: Object.values(error.constraints || {}),
      value: error.value,
    }));
  }
}